"""
用户相关接口
作者：资深Flask讲师
功能：登录、退出、刷新token、用户信息、注册等
"""

from flask import Blueprint, jsonify, request, current_app
from myflask.tools.myjwt import JWTUtil
from myflask.tools.myredis import RedisUtil
from myflask.tools.bd import db
from myflask.models.user import User

user_blue = Blueprint('user_blue', __name__)


@user_blue.route('/reg', methods=['POST'])
def reg():
    """
    用户注册接口
    请求体：{"user": "zhangsan", "password": "123456", "real_name": "张三", "email": "zhangsan@example.com"}
    返回：{"code": 200, "message": "注册成功"}
    """
    try:
        data = request.get_json()
        
        if not data:
            return jsonify({
                "code": 400,
                "message": "请求数据格式错误"
            }), 400
        
        user = data.get('user', '').strip()
        password = data.get('password', '').strip()
        real_name = data.get('real_name', '').strip()
        email = data.get('email', '').strip()
        
        # 数据验证
        if not user or not password:
            return jsonify({
                "code": 400,
                "message": "用户名和密码不能为空"
            }), 400
        
        if len(user) < 3 or len(user) > 50:
            return jsonify({
                "code": 400,
                "message": "用户名长度必须在3-50个字符之间"
            }), 400
        
        if len(password) < 6:
            return jsonify({
                "code": 400,
                "message": "密码长度不能少于6位"
            }), 400
        
        # 检查用户名是否已存在
        existing_user = User.query.filter_by(user=user).first()
        if existing_user:
            return jsonify({
                "code": 400,
                "message": "用户名已存在"
            }), 400
        
        # 创建新用户（默认角色为employee-普通员工）
        new_user = User(
            user=user,
            real_name=real_name if real_name else None,
            email=email if email else None,
            role='employee',  # 默认为普通员工
            status=1
        )
        new_user.set_password(password)
        
        # 保存到数据库
        db.session.add(new_user)
        db.session.commit()
        
        return jsonify({
            "code": 200,
            "message": "注册成功，请登录"
        })
        
    except Exception as e:
        db.session.rollback()
        return jsonify({
            "code": 500,
            "message": f"注册失败: {str(e)}"
        }), 500


@user_blue.route('/login', methods=['POST'])
def login():
    """
    用户登录接口
    请求体：{"user": "admin", "password": "123456"}
    返回：{"code": 200, "message": "登录成功", "data": {"access_token": "...", "refresh_token": "..."}}
    """
    try:
        # 1. 获取POST请求的JSON数据
        data = request.get_json()
        
        if not data:
            return jsonify({
                "code": 400,
                "message": "请求数据格式错误，请使用JSON格式"
            }), 400
        
        username = data.get('user', '').strip()
        password = data.get('password', '').strip()
        
        # 2. 数据验证
        if not username or not password:
            return jsonify({
                "code": 400,
                "message": "用户名和密码不能为空"
            }), 400
        
        # 3. 从数据库查询用户
        user = User.query.filter_by(user=username).first()
        
        if not user:
            return jsonify({
                "code": 401,
                "message": "用户名或密码错误"
            }), 401
        
        # 4. 验证密码
        if not user.check_password(password):
            return jsonify({
                "code": 401,
                "message": "用户名或密码错误"
            }), 401
        
        # 5. 检查用户状态
        if user.status != 1:
            return jsonify({
                "code": 403,
                "message": "账号已被禁用，请联系管理员"
            }), 403
        
        # 6. 生成token（访问token 30分钟，刷新token 60分钟）
        user_data = {
            'user_id': user.id,
            'username': user.user,
            'role': user.role,
            'department_id': user.department_id
        }
        
        tokens = JWTUtil.generate_tokens(user_data)
        
        # 7. 返回token和用户信息给前端
        return jsonify({
            "code": 200,
            "message": "登录成功",
            "data": {
                "access_token": tokens['access_token'],
                "refresh_token": tokens['refresh_token'],
                "user": user.to_dict(),
                "expires_in": current_app.config.get('JWT_ACCESS_TOKEN_EXPIRES', 30) * 60  # 秒
            }
        })
        
    except Exception as e:
        return jsonify({
            "code": 500,
            "message": f"登录失败: {str(e)}"
        }), 500


@user_blue.route('/logout', methods=['POST'])
def logout():
    """
    退出登录接口
    请求头：Authorization: Bearer <access_token>
    返回：{"code": 200, "message": "退出成功"}
    """
    try:
        # 1. 从请求头获取token
        auth_header = request.headers.get('Authorization')
        
        if not auth_header or not auth_header.startswith('Bearer '):
            return jsonify({
                "code": 401,
                "message": "未提供有效的token"
            }), 401
        
        # 提取token（去掉"Bearer "前缀）
        token = auth_header[7:]
        
        # 2. 将token加入Redis黑名单
        # 设置过期时间为token的剩余有效期（这里简化为1小时）
        expire_seconds = current_app.config.get('JWT_REFRESH_TOKEN_EXPIRES', 60) * 60
        
        success = RedisUtil.add_to_blacklist(token, expire_seconds)
        
        if success:
            return jsonify({
                "code": 200,
                "message": "退出登录成功"
            })
        else:
            return jsonify({
                "code": 200,
                "message": "退出登录成功（Redis不可用，token未加入黑名单）"
            })
        
    except Exception as e:
        return jsonify({
            "code": 500,
            "message": f"退出登录失败: {str(e)}"
        }), 500


@user_blue.route('/refresh_token', methods=['POST'])
def refresh_token():
    """
    刷新token接口
    请求体：{"refresh_token": "..."}
    返回：{"code": 200, "message": "刷新成功", "data": {"access_token": "..."}}
    """
    try:
        # 1. 获取refresh_token
        data = request.get_json()
        
        if not data:
            return jsonify({
                "code": 400,
                "message": "请求数据格式错误"
            }), 400
        
        refresh_token_str = data.get('refresh_token', '').strip()
        
        if not refresh_token_str:
            return jsonify({
                "code": 400,
                "message": "refresh_token不能为空"
            }), 400
        
        # 2. 检查refresh_token是否在黑名单中
        if RedisUtil.is_in_blacklist(refresh_token_str):
            return jsonify({
                "code": 401,
                "message": "refresh_token已失效，请重新登录"
            }), 401
        
        # 3. 验证refresh_token
        try:
            payload = JWTUtil.decode(refresh_token_str)
            
            # 验证是否为refresh类型的token
            if payload.get('type') != 'refresh':
                return jsonify({
                    "code": 401,
                    "message": "请提供有效的refresh_token"
                }), 401
            
        except Exception as e:
            return jsonify({
                "code": 401,
                "message": str(e)
            }), 401
        
        # 4. 生成新的access_token
        user_data = {
            'user_id': payload.get('user_id'),
            'username': payload.get('username'),
            'role': payload.get('role'),
            'department_id': payload.get('department_id')
        }
        
        new_access_token = JWTUtil.encode(user_data, expire_minutes=30)
        
        # 5. 返回新的access_token
        return jsonify({
            "code": 200,
            "message": "刷新成功",
            "data": {
                "access_token": new_access_token,
                "expires_in": current_app.config.get('JWT_ACCESS_TOKEN_EXPIRES', 30) * 60
            }
        })
        
    except Exception as e:
        return jsonify({
            "code": 500,
            "message": f"刷新token失败: {str(e)}"
        }), 500


@user_blue.route('/userinfo', methods=['GET'])
def userinfo():
    """
    获取用户信息接口（需要token验证）
    请求头：Authorization: Bearer <access_token>
    返回：{"code": 200, "message": "成功", "data": {...}}
    """
    try:
        # 从request.user_info中获取用户信息（由拦截器解析token后设置）
        user_info = getattr(request, 'user_info', None)
        
        if not user_info:
            return jsonify({
                "code": 401,
                "message": "未获取到用户信息"
            }), 401
        
        # 从数据库获取最新用户信息
        user_id = user_info.get('user_id')
        user = User.query.get(user_id)
        
        if not user:
            return jsonify({
                "code": 404,
                "message": "用户不存在"
            }), 404
        
        return jsonify({
            "code": 200,
            "message": "获取用户信息成功",
            "data": user.to_dict()
        })
        
    except Exception as e:
        return jsonify({
            "code": 500,
            "message": f"获取用户信息失败: {str(e)}"
        }), 500
